home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / term-source.lha / SerialIO.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  13KB  |  794 lines

  1. /*
  2. **    SerialIO.c
  3. **
  4. **    Serial read/write routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. STATIC LONG __aligned    ReadQueued    = FALSE,
  13.             WriteQueued    = FALSE;
  14.  
  15.     /* DeleteLED():
  16.      *
  17.      *    Dummy routine, the real implementation may
  18.      *    follow in a later release.
  19.      */
  20.  
  21. VOID
  22. DeleteLED()
  23. {
  24. }
  25.  
  26.     /* CreateLED():
  27.      *
  28.      *    Dummy routine, the real implementation may
  29.      *    follow in a later release.
  30.      */
  31.  
  32. VOID
  33. CreateLED()
  34. {
  35. }
  36.  
  37.     /* ResetSerialRead():
  38.      *
  39.      *    Reset the read status.
  40.      */
  41.  
  42. VOID
  43. ResetSerialRead()
  44. {
  45.     ReadQueued = FALSE;
  46. }
  47.  
  48.     /* CheckSerialRead():
  49.      *
  50.      *    Check if a read request is finished.
  51.      */
  52.  
  53. BOOLEAN
  54. CheckSerialRead()
  55. {
  56.     if(ReadRequest && ReadQueued)
  57.     {
  58.         if(CheckIO(ReadRequest))
  59.             return(TRUE);
  60.     }
  61.  
  62.     return(FALSE);
  63. }
  64.  
  65.     /* WaitSerialRead():
  66.      *
  67.      *    Wait for the read request to terminate.
  68.      */
  69.  
  70. BYTE
  71. WaitSerialRead()
  72. {
  73.     if(ReadRequest && ReadQueued)
  74.     {
  75.         ReadQueued = FALSE;
  76.  
  77.         return(WaitIO(ReadRequest));
  78.     }
  79.     else
  80.         return(0);
  81. }
  82.  
  83.     /* FlushSerialRead():
  84.      *
  85.      *    Forget about the current contents of the serial
  86.      *    read buffer.
  87.      */
  88.  
  89. BYTE
  90. FlushSerialRead()
  91. {
  92.     if(ReadRequest)
  93.     {
  94.         BOOL    WasRunning;
  95.         BYTE    Error;
  96.  
  97.         if(WasRunning = ReadQueued)
  98.             StopSerialRead();
  99.  
  100.         ReadRequest -> IOSer . io_Command = CMD_CLEAR;
  101.  
  102.         Error = DoIO(ReadRequest);
  103.  
  104.         if(WasRunning)
  105.             StartSerialRead(ReadBuffer,1);
  106.  
  107.         return(Error);
  108.     }
  109.     else
  110.         return(SerErr_DevBusy);
  111. }
  112.  
  113.     /* StopSerialRead():
  114.      *
  115.      *    Force a read request to terminate.
  116.      */
  117.  
  118. VOID
  119. StopSerialRead()
  120. {
  121.     if(ReadRequest && ReadQueued)
  122.     {
  123.         if(!CheckIO(ReadRequest))
  124.             AbortIO(ReadRequest);
  125.  
  126.         WaitIO(ReadRequest);
  127.  
  128.         ReadQueued = FALSE;
  129.     }
  130. }
  131.  
  132.     /* StartSerialRead(register ULONG Length,register APTR Data):
  133.      *
  134.      *    Start a serial read request asynchronously.
  135.      */
  136.  
  137. VOID __regargs
  138. StartSerialRead(register APTR Data,register ULONG Length)
  139. {
  140.     if(ReadRequest)
  141.     {
  142.         if(ReadQueued)
  143.             StopSerialRead();
  144.  
  145.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  146.         ReadRequest -> IOSer . io_Length    = Length;
  147.         ReadRequest -> IOSer . io_Data        = Data;
  148.  
  149.         ClrSignal(1L << ReadPort -> mp_SigBit);
  150.  
  151.         SendIO(ReadRequest);
  152.  
  153.         ReadQueued = TRUE;
  154.     }
  155. }
  156.  
  157.     /* StartSerialReadQuick(register ULONG Length,register APTR Data):
  158.      *
  159.      *    Start a serial read request asynchronously, using the
  160.      *    quick I/O mode.
  161.      */
  162.  
  163. BOOL __regargs
  164. StartSerialReadQuick(register APTR Data,register ULONG Length)
  165. {
  166.     if(ReadRequest)
  167.     {
  168.         if(ReadQueued)
  169.             StopSerialRead();
  170.  
  171.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  172.         ReadRequest -> IOSer . io_Length    = Length;
  173.         ReadRequest -> IOSer . io_Data        = Data;
  174.         ReadRequest -> IOSer . io_Flags        = IOF_QUICK;
  175.  
  176.         ClrSignal(1L << ReadPort -> mp_SigBit);
  177.  
  178.         BeginIO(ReadRequest);
  179.  
  180.         if(ReadRequest -> IOSer . io_Flags & IOF_QUICK)
  181.         {
  182.             WaitIO(ReadRequest);    // In case some weird driver has patches installed here and needs to be called.
  183.  
  184.             return(TRUE);
  185.         }
  186.         else
  187.             ReadQueued = TRUE;
  188.     }
  189.  
  190.     return(FALSE);
  191. }
  192.  
  193.     /* DoSerialRead(register ULONG Length,register APTR Data):
  194.      *
  195.      *    Perform a read request synchronously.
  196.      */
  197.  
  198. BYTE __regargs
  199. DoSerialRead(register APTR Data,register ULONG Length)
  200. {
  201.     if(ReadRequest)
  202.     {
  203.         if(ReadQueued)
  204.             StopSerialRead();
  205.  
  206.         ReadRequest -> IOSer . io_Command    = CMD_READ;
  207.         ReadRequest -> IOSer . io_Length    = Length;
  208.         ReadRequest -> IOSer . io_Data        = Data;
  209.  
  210.         return(DoIO(ReadRequest));
  211.     }
  212.     else
  213.         return(IOERR_SELFTEST);
  214. }
  215.  
  216.     /* ResetSerialWrite():
  217.      *
  218.      *    Reset the write status.
  219.      */
  220.  
  221. VOID
  222. ResetSerialWrite()
  223. {
  224.     WriteQueued = FALSE;
  225. }
  226.  
  227.     /* CheckSerialWrite():
  228.      *
  229.      *    Check if a write request is finished.
  230.      */
  231.  
  232. BOOLEAN
  233. CheckSerialWrite()
  234. {
  235.     if(WriteRequest && WriteQueued)
  236.     {
  237.         if(!CheckIO(WriteRequest))
  238.             return(TRUE);
  239.     }
  240.  
  241.     return(FALSE);
  242. }
  243.  
  244.     /* WaitSerialWrite():
  245.      *
  246.      *    Wait for the write request to terminate.
  247.      */
  248.  
  249. BYTE
  250. WaitSerialWrite()
  251. {
  252.     if(WriteRequest && WriteQueued)
  253.     {
  254.         WriteQueued = FALSE;
  255.  
  256.         return(WaitIO(WriteRequest));
  257.     }
  258.     else
  259.         return(0);
  260. }
  261.  
  262.     /* StopSerialWrite():
  263.      *
  264.      *    Force a write request to terminate.
  265.      */
  266.  
  267. VOID
  268. StopSerialWrite()
  269. {
  270.     if(WriteRequest && WriteQueued)
  271.     {
  272.         if(!CheckIO(WriteRequest))
  273.             AbortIO(WriteRequest);
  274.  
  275.         WaitIO(WriteRequest);
  276.  
  277.         WriteQueued = FALSE;
  278.     }
  279. }
  280.  
  281.     /* StartSerialWrite(register ULONG Length,register APTR Data):
  282.      *
  283.      *    Start a serial write request asynchronously.
  284.      */
  285.  
  286. VOID __regargs
  287. StartSerialWrite(register APTR Data,register ULONG Length)
  288. {
  289.     if(WriteRequest)
  290.     {
  291.         if(WriteQueued)
  292.             StopSerialWrite();
  293.  
  294.         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  295.         WriteRequest -> IOSer . io_Length    = Length;
  296.         WriteRequest -> IOSer . io_Data        = Data;
  297.  
  298.         ClrSignal(1L << WriteRequest -> IOSer . io_Message . mn_ReplyPort -> mp_SigBit);
  299.  
  300.         SendIO(WriteRequest);
  301.  
  302.         WriteQueued = TRUE;
  303.     }
  304. }
  305.  
  306.     /* DoSerialWrite(register ULONG Length,register APTR Data):
  307.      *
  308.      *    Perform a write request synchronously.
  309.      */
  310.  
  311. BYTE __regargs
  312. DoSerialWrite(register APTR Data,register ULONG Length)
  313. {
  314.     if(WriteRequest)
  315.     {
  316.         if(WriteQueued)
  317.             StopSerialWrite();
  318.  
  319.         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  320.         WriteRequest -> IOSer . io_Length    = Length;
  321.         WriteRequest -> IOSer . io_Data        = Data;
  322.  
  323.         return(DoIO(WriteRequest));
  324.     }
  325.     else
  326.         return(IOERR_SELFTEST);
  327. }
  328.  
  329.     /* DoSerialCmd(register UWORD Command):
  330.      *
  331.      *    Perform single command.
  332.      */
  333.  
  334. BYTE __regargs
  335. DoSerialCmd(register UWORD Command)
  336. {
  337.     if(WriteRequest)
  338.     {
  339.         if(WriteQueued)
  340.             StopSerialWrite();
  341.  
  342.         WriteRequest -> IOSer . io_Command = Command;
  343.  
  344.         return(DoIO(WriteRequest));
  345.     }
  346.     else
  347.         return(IOERR_SELFTEST);
  348. }
  349.  
  350.     /* GetSerialWaiting():
  351.      *
  352.      *    Query the number of bytes still waiting to be read
  353.      *    from the serial port.
  354.      */
  355.  
  356. ULONG
  357. GetSerialWaiting()
  358. {
  359.     if(WriteRequest)
  360.     {
  361.         if(WriteQueued)
  362.             StopSerialWrite();
  363.  
  364.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  365.  
  366.         DoIO(WriteRequest);
  367.  
  368.         return(WriteRequest -> IOSer . io_Actual);
  369.     }
  370.     else
  371.         return(0);
  372. }
  373.  
  374.     /* GetSerialStatus():
  375.      *
  376.      *    Query the current serial port status.
  377.      */
  378.  
  379. UWORD
  380. GetSerialStatus()
  381. {
  382.     if(WriteRequest)
  383.     {
  384.         if(WriteQueued)
  385.             StopSerialWrite();
  386.  
  387.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  388.  
  389.         DoIO(WriteRequest);
  390.  
  391.         return(WriteRequest -> io_Status);
  392.     }
  393.     else
  394.         return(CIAF_COMCD | CIAF_COMDSR);
  395. }
  396.  
  397.     /* GetSerialInfo(register ULONG *Waiting,register UWORD *Status):
  398.      *
  399.      *    Query both the number of bytes waiting to be read and
  400.      *    the current serial status.
  401.      */
  402.  
  403. VOID __regargs
  404. GetSerialInfo(register ULONG *Waiting,register UWORD *Status)
  405. {
  406.     if(WriteRequest)
  407.     {
  408.         if(WriteQueued)
  409.             StopSerialWrite();
  410.  
  411.         WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  412.  
  413.         DoIO(WriteRequest);
  414.  
  415.         *Waiting    = WriteRequest -> IOSer . io_Actual;
  416.         *Status        = WriteRequest -> io_Status;
  417.     }
  418.     else
  419.     {
  420.         *Waiting    = 0;
  421.         *Status        = CIAF_COMCD | CIAF_COMDSR;
  422.     }
  423. }
  424.  
  425.     /* SetSerialAttributes():
  426.      *
  427.      *    Set the serial driver attributes.
  428.      */
  429.  
  430. STATIC VOID
  431. SetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  432. {
  433.     struct TagItem *Tag;
  434.  
  435.     while(Tag = NextTagItem(&Tags))
  436.     {
  437.         switch(Tag -> ti_Tag)
  438.         {
  439.             case SERA_Baud:
  440.  
  441.                 Request -> io_Baud = Tag -> ti_Data;
  442.                 break;
  443.  
  444.             case SERA_BreakTime:
  445.  
  446.                 Request -> io_BrkTime = Tag -> ti_Data;
  447.                 break;
  448.  
  449.             case SERA_BitsPerChar:
  450.  
  451.                 Request -> io_ReadLen    = Tag -> ti_Data;
  452.                 Request -> io_WriteLen    = Tag -> ti_Data;
  453.                 break;
  454.  
  455.             case SERA_StopBits:
  456.  
  457.                 Request -> io_StopBits = Tag -> ti_Data;
  458.                 break;
  459.  
  460.             case SERA_BufferSize:
  461.  
  462.                 Request -> io_RBufLen = Tag -> ti_Data;
  463.                 break;
  464.  
  465.             case SERA_Parity:
  466.  
  467.                 Request -> io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  468.                 Request -> io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  469.  
  470.                 switch(Tag -> ti_Data)
  471.                 {
  472.                     case PARITY_EVEN:
  473.  
  474.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  475.                         break;
  476.  
  477.                     case PARITY_ODD:
  478.  
  479.                         Request -> io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  480.                         break;
  481.  
  482.                     case PARITY_MARK:
  483.  
  484.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  485.                         Request -> io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  486.                         break;
  487.  
  488.                     case PARITY_SPACE:
  489.  
  490.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  491.                         Request -> io_ExtFlags |= SEXTF_MSPON;
  492.                         break;
  493.                 }
  494.  
  495.                 break;
  496.  
  497.             case SERA_Handshaking:
  498.  
  499.                 if(Tag -> ti_Data == HANDSHAKING_NONE)
  500.                     Request -> io_SerFlags &= ~SERF_7WIRE;
  501.                 else
  502.                     Request -> io_SerFlags |=  SERF_7WIRE;
  503.  
  504.                 break;
  505.  
  506.             case SERA_HighSpeed:
  507.  
  508.                 if(Tag -> ti_Data)
  509.                     Request -> io_SerFlags |=  SERF_RAD_BOOGIE;
  510.                 else
  511.                     Request -> io_SerFlags &= ~SERF_RAD_BOOGIE;
  512.  
  513.                 break;
  514.  
  515.             case SERA_Shared:
  516.  
  517.                 if(Tag -> ti_Data)
  518.                     Request -> io_SerFlags |=  SERF_SHARED;
  519.                 else
  520.                     Request -> io_SerFlags &= ~SERF_SHARED;
  521.  
  522.                 break;
  523.         }
  524.     }
  525.  
  526.     Request -> io_SerFlags |= SERF_XDISABLED;
  527. }
  528.  
  529.     /* GetSerialAttributes():
  530.      *
  531.      *    Get the serial driver attributes.
  532.      */
  533.  
  534. STATIC ULONG
  535. GetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  536. {
  537.     struct TagItem    *Tag;
  538.     ULONG        *Data,
  539.              Result = NULL;
  540.  
  541.     while(Tag = NextTagItem(&Tags))
  542.     {
  543.         if(!(Data = (ULONG *)Tag -> ti_Data))
  544.             Data = &Result;
  545.  
  546.         switch(Tag -> ti_Tag)
  547.         {
  548.             case SERA_Baud:
  549.  
  550.                 *Data = Request -> io_Baud;
  551.                 break;
  552.  
  553.             case SERA_BreakTime:
  554.  
  555.                 *Data = Request -> io_BrkTime;
  556.                 break;
  557.  
  558.             case SERA_BitsPerChar:
  559.  
  560.                 *Data = Request -> io_ReadLen;
  561.                 break;
  562.  
  563.             case SERA_StopBits:
  564.  
  565.                 *Data = Request -> io_StopBits;
  566.                 break;
  567.  
  568.             case SERA_BufferSize:
  569.  
  570.                 *Data = Request -> io_RBufLen;
  571.                 break;
  572.  
  573.             case SERA_Parity:
  574.  
  575.                 Request -> io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  576.                 Request -> io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  577.  
  578.                 switch(Tag -> ti_Data)
  579.                 {
  580.                     case PARITY_EVEN:
  581.  
  582.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  583.                         break;
  584.  
  585.                     case PARITY_ODD:
  586.  
  587.                         Request -> io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  588.                         break;
  589.  
  590.                     case PARITY_MARK:
  591.  
  592.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  593.                         Request -> io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  594.                         break;
  595.  
  596.                     case PARITY_SPACE:
  597.  
  598.                         Request -> io_SerFlags |= SERF_PARTY_ON;
  599.                         Request -> io_ExtFlags |= SEXTF_MSPON;
  600.                         break;
  601.                 }
  602.  
  603.                 switch(Request -> io_ExtFlags & (SEXTF_MSPON | SEXTF_MARK))
  604.                 {
  605.                     case SEXTF_MSPON | SEXTF_MARK:
  606.  
  607.                         *Data = PARITY_MARK;
  608.                         break;
  609.  
  610.                     case SEXTF_MSPON:
  611.  
  612.                         *Data = PARITY_SPACE;
  613.                         break;
  614.  
  615.                     default:
  616.  
  617.                         switch(Request -> io_SerFlags & (SERF_PARTY_ON | SERF_PARTY_ODD))
  618.                         {
  619.                             case SERF_PARTY_ON | SERF_PARTY_ODD:
  620.  
  621.                                 *Data = PARITY_ODD;
  622.                                 break;
  623.  
  624.                             case SERF_PARTY_ON:
  625.  
  626.                                 *Data = PARITY_EVEN;
  627.                                 break;
  628.  
  629.                             default:
  630.  
  631.                                 *Data = PARITY_NONE;
  632.                                 break;
  633.                         }
  634.  
  635.                         break;
  636.                 }
  637.  
  638.                 break;
  639.  
  640.             case SERA_Handshaking:
  641.  
  642.                 if(Request -> io_SerFlags & SERF_7WIRE)
  643.                     *Data = TRUE;
  644.                 else
  645.                     *Data = FALSE;
  646.  
  647.                 break;
  648.  
  649.             case SERA_HighSpeed:
  650.  
  651.                 if(Request -> io_SerFlags & SERF_RAD_BOOGIE)
  652.                     *Data = TRUE;
  653.                 else
  654.                     *Data = FALSE;
  655.  
  656.                 break;
  657.  
  658.             case SERA_Shared:
  659.  
  660.                 if(Request -> io_SerFlags & SERF_SHARED)
  661.                     *Data = TRUE;
  662.                 else
  663.                     *Data = FALSE;
  664.  
  665.                 break;
  666.         }
  667.     }
  668.  
  669.     return(Result);
  670. }
  671.  
  672.     /* SetBothSerialAttributes():
  673.      *
  674.      *    Set the serial read driver parameters.
  675.      */
  676.  
  677. BYTE __stdargs
  678. SetBothSerialAttributes(Tag FirstTag,...)
  679. {
  680.     if(ReadRequest && WriteRequest)
  681.     {
  682.         BYTE Result;
  683.  
  684.         if(ReadQueued)
  685.             StopSerialRead();
  686.  
  687.         if(WriteQueued)
  688.             StopSerialWrite();
  689.  
  690.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  691.  
  692.         if(ReadRequest -> IOSer . io_Device)
  693.         {
  694.             ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  695.  
  696.             Result = DoIO(ReadRequest);
  697.         }
  698.         else
  699.             Result = 0;
  700.  
  701.         if(!Result)
  702.         {
  703.             struct MsgPort *WritePort = WriteRequest -> IOSer . io_Message . mn_ReplyPort;
  704.  
  705.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  706.  
  707.             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  708.         }
  709.  
  710.         return(Result);
  711.     }
  712.     else
  713.         return(IOERR_SELFTEST);
  714. }
  715.  
  716.     /* SetSerialReadAttributes():
  717.      *
  718.      *    Set the serial read driver parameters.
  719.      */
  720.  
  721. BYTE __stdargs
  722. SetSerialReadAttributes(Tag FirstTag,...)
  723. {
  724.     if(ReadRequest)
  725.     {
  726.         if(ReadQueued)
  727.             StopSerialRead();
  728.  
  729.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  730.  
  731.         if(ReadRequest -> IOSer . io_Device)
  732.         {
  733.             ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  734.  
  735.             return(DoIO(ReadRequest));
  736.         }
  737.         else
  738.             return(0);
  739.     }
  740.     else
  741.         return(IOERR_SELFTEST);
  742. }
  743.  
  744.     /* SetSerialWriteAttributes():
  745.      *
  746.      *    Set the serial write driver parameters.
  747.      */
  748.  
  749. BYTE __stdargs
  750. SetSerialWriteAttributes(Tag FirstTag,...)
  751. {
  752.     if(WriteRequest)
  753.     {
  754.         if(WriteQueued)
  755.             StopSerialWrite();
  756.  
  757.         SetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag);
  758.  
  759.         WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  760.  
  761.         return(DoIO(WriteRequest));
  762.     }
  763.     else
  764.         return(IOERR_SELFTEST);
  765. }
  766.  
  767.     /* GetSerialReadAttributes():
  768.      *
  769.      *    Get the serial read driver parameters.
  770.      */
  771.  
  772. ULONG __stdargs
  773. GetSerialReadAttributes(Tag FirstTag,...)
  774. {
  775.     if(ReadRequest)
  776.         return(GetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag));
  777.     else
  778.         return(NULL);
  779. }
  780.  
  781.     /* GetSerialWriteAttributes():
  782.      *
  783.      *    Get the serial write driver parameters.
  784.      */
  785.  
  786. ULONG __stdargs
  787. GetSerialWriteAttributes(Tag FirstTag,...)
  788. {
  789.     if(WriteRequest)
  790.         return(GetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag));
  791.     else
  792.         return(NULL);
  793. }
  794.